home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / iconv8_s.arc / ICONT.ARC / LMEM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-28  |  13.9 KB  |  588 lines

  1. /*
  2.  * lmem.c -- memory initialization and allocation; also parses arguments.
  3.  */
  4.  
  5. #include "..\h\config.h"
  6. #include "general.h"
  7. #include "tproto.h"
  8. #include "globals.h"
  9. #include "link.h"
  10.  
  11. /*
  12.  * The following code is operating-system dependent [@lmem.01].  It includes
  13.  *  files that are system dependent.
  14.  */
  15.  
  16. #if PORT
  17.    /* nothing is needed */
  18. Deliberate Syntax Error
  19. #endif                    /* PORT */
  20.  
  21. #if AMIGA || ATARI_ST || HIGHC_386 || MACINTOSH || VMS
  22.    /* nothing is needed */
  23. #endif                    /* AMIGA || ATARI_AT || HIGHC_386 ... */
  24.  
  25. #if MSDOS
  26. #if MICROSOFT
  27. #include <sys\types.h>
  28. #include <sys\stat.h>
  29. #endif                    /* MICROSOFT */
  30. #if TURBO
  31. #include <sys\stat.h>
  32. #endif                    /* TURBO */
  33. #endif                    /* MSDOS */
  34.  
  35. #if MVS || VM
  36. #if SASC
  37. #include <fcntl.h>
  38. #else                    /* SASC */
  39. #include <file.h>
  40. #endif                    /* SASC */
  41. #endif                    /* MVS || VM */
  42.  
  43. #if OS2
  44. #if MICROSOFT
  45. #include <sys\types.h>
  46. #include <sys\stat.h>
  47. #endif                    /* MICROSOFT */
  48. #endif                    /* OS2 */
  49.  
  50. #if UNIX
  51. #ifndef ATT3B
  52. #ifdef CRAY
  53. #define word word_fubar
  54. #include <sys\types.h>
  55. #include <sys\stat.h>
  56. #undef word
  57. #else                    /* CRAY */
  58. #include <sys\types.h>
  59. #include <sys\stat.h>
  60. #endif                    /* CRAY */
  61. #endif                    /* ATT3B */
  62. #endif                    /* UNIX */
  63.  
  64. /*
  65.  * End of operating-system specific code.
  66.  */
  67.  
  68. /*
  69.  * Prototypes.
  70.  */
  71.  
  72. hidden struct    lfile *alclfile    Params((char *name));
  73. hidden int    canread        Params((char *file));
  74. hidden int    trypath        Params((char *name,char *file));
  75.  
  76. #ifdef MultipleRuns
  77. hidden novalue    freelfile    Params((struct lfile *p));
  78. #endif                    /* MultipleRuns */
  79.  
  80. /*
  81.  * Memory initialization
  82.  */
  83.  
  84. struct gentry **lghash;        /* hash area for global table */
  85. struct ientry **lihash;        /* hash area for identifier table */
  86. struct fentry **lfhash;        /* hash area for field table */
  87.  
  88. struct lentry *lltable;        /* local table */
  89. struct gentry *lgtable;        /* global table */
  90. struct centry *lctable;        /* constant table */
  91. struct ientry *litable;        /* identifier table */
  92. struct fentry *lftable;        /* field table headers */
  93. struct rentry *lrtable;        /* field table record lists */
  94. struct ipc_fname *fnmtbl;    /* table associating ipc with file name */
  95. struct ipc_line *lntable;    /* table associating ipc with line number */
  96.  
  97. char *lsspace;            /* string space */
  98. word *labels;            /* label table */
  99. char *codeb;            /* generated code space */
  100.  
  101. struct gentry *lgfree;        /* free pointer for global table */
  102. struct ientry *lifree;        /* free pointer for identifier table */
  103. struct fentry *lffree;        /* free pointer for field table headers */
  104. struct rentry *lrfree;        /* free pointer for field table record lists */
  105. struct ipc_fname *fnmfree;    /* free pointer for ipc/file name table */
  106. struct ipc_line *lnfree;    /* free pointer for ipc/line number table */
  107. char *lsfree;            /* free pointer for string space */
  108. char *codep;            /* free pointer for code space */
  109.  
  110. char *lsend;            /* pointer to end of string space */
  111.  
  112. static char *ipath;        /* path for iconx */
  113.  
  114. #ifdef MultipleRuns
  115. extern word pc;
  116. extern int fatals;
  117. extern int nlflag;
  118. extern int lstatics;
  119. extern int nfields;
  120. #endif                    /* MultipleRuns */
  121.  
  122. /*
  123.  * linit - scan the command line arguments and initialize data structures.
  124.  */
  125. novalue linit()
  126.    {
  127.    struct gentry **gp;
  128.    struct ientry **ip;
  129.    struct fentry **fp;
  130.  
  131.    llfiles = NULL;        /* Zero queue of files to link. */
  132.  
  133. #ifdef EnvVars
  134.    ipath = getenv("IPATH");
  135. #else                    /* EnvVars */
  136.    ipath = NULL;
  137. #endif                    /* EnvVars */
  138.  
  139.    if (ipath == NULL)
  140.  
  141. /*
  142.  * The following code is operating-system dependent [@lmem.02].  Set default for
  143.  *  IPATH.
  144.  */
  145.  
  146. #if PORT
  147.    /* something is needed */
  148. Deliberate Syntax Error
  149. #endif                    /* PORT */
  150.  
  151. #if AMIGA
  152.    /*
  153.     * There is no environment, so set ipath to the null string. The
  154.     *  current directory is searched anyway and there is no symbol
  155.     *  to force current path search.
  156.     */
  157.       ipath = "";
  158. #endif                    /* AMIGA */
  159.  
  160. #if ATARI_ST || UNIX
  161.       ipath = ".";
  162. #endif                    /* ATARI_ST || UNIX */
  163.  
  164. #if HIGHC_386 || MSDOS || OS2
  165.       ipath = ";";
  166. #endif                    /* HIGHC_386 || MSDOS || OS2 */
  167.  
  168. #if MACINTOSH
  169. #if MPW || LSC
  170.       ipath = ":";
  171. #endif                    /* MPW || LSC */
  172. #endif                    /* MACINTOSH */
  173.  
  174. #if MVS || VM
  175.       ipath = "";
  176. #endif                    /* MVS || VS */
  177.  
  178. #if VMS
  179.       ipath = "[]";
  180. #endif                    /* VMS */
  181.  
  182. /*
  183.  * End of operating-system specific code.
  184.  */
  185.  
  186.    /*
  187.     * Allocate the various data structures that are used by the linker.
  188.     */
  189.    lghash   = (struct gentry **) tcalloc(ghsize, sizeof(struct gentry *));
  190.    lihash   = (struct ientry **) tcalloc(ihsize, sizeof(struct ientry *));
  191.    lfhash   = (struct fentry **) tcalloc(fhsize, sizeof(struct fentry *));
  192.  
  193.    lltable  = (struct lentry *) tcalloc(lsize, sizeof(struct lentry));
  194.    lctable  = (struct centry *) tcalloc(csize, sizeof(struct centry));
  195.  
  196.    lffree = lftable  = (struct fentry *) tcalloc(fsize, sizeof(struct fentry));
  197.    lgfree = lgtable  = (struct gentry *) tcalloc(gsize, sizeof(struct gentry));
  198.    lifree = litable  = (struct ientry *) tcalloc(isize, sizeof(struct ientry ));
  199.    lnfree = lntable  = (struct ipc_line*)tcalloc(nsize,sizeof(struct ipc_line));
  200.    lrfree = lrtable  = (struct rentry *) tcalloc(rsize, sizeof(struct rentry));
  201.  
  202.    lsfree = lsspace = (char *) tcalloc(stsize, sizeof(char));
  203.    lsend = lsspace + stsize - 1;
  204.  
  205.    fnmtbl = (struct ipc_fname *) tcalloc(fnmsize, sizeof(struct ipc_fname));
  206.    fnmfree = fnmtbl;
  207.  
  208.    labels  = (word *) tcalloc(maxlabels, sizeof(word));
  209.    codep = codeb = (char *) tcalloc(maxcode, 1);
  210.  
  211.    /*
  212.     * Zero out the hash tables.
  213.     */
  214.    for (gp = lghash; gp < &lghash[ghsize]; gp++)
  215.       *gp = NULL;
  216.    for (ip = lihash; ip < &lihash[ihsize]; ip++)
  217.       *ip = NULL;
  218.    for (fp = lfhash; fp < &lfhash[fhsize]; fp++)
  219.       *fp = NULL;
  220.  
  221. #ifdef MultipleRuns
  222.  
  223.    /*
  224.     * Initializations required for repeated program runs.
  225.     */
  226.  
  227.    pc = 0;                /* In lcode.c    */
  228.    nrecords = 0;            /* In lglob.c    */
  229.  
  230. #ifdef EvalTrace
  231.    colmno = 0;                /* In link.c    */
  232. #endif                    /* EvalTrace */
  233.  
  234.    lineno = 0;                /* In link.c    */
  235.    fatals = 0;                /* In link.c    */
  236.    nlflag = 0;                /* In llex.c    */
  237.    lstatics = 0;            /* In lsym.c    */
  238.    nfields = 0;                /* In lsym.c    */
  239. #endif                    /* MultipleRuns */
  240.  
  241.    /*
  242.     * Install "main" as a global variable in order to insure that it
  243.     *  is the first global variable.  iconx/start.s depends on main
  244.     *  being global number 0.
  245.     */
  246.    putglobal(instid("main"), F_Global, 0, 0);
  247.    }
  248.  
  249. #ifdef DeBugLinker
  250. /*
  251.  * dumplfiles - print the list of files to link.  Used for debugging only.
  252.  */
  253.  
  254. novalue dumplfiles()
  255.    {
  256.    struct lfile *p,*lfls;
  257.  
  258.    fprintf(stderr,"lfiles:\n");
  259.    lfls = llfiles;
  260.    while (p = getlfile(&lfls))
  261.        fprintf(stderr,"'%s'\n",p->lf_name);
  262.    fflush(stderr);
  263.    }
  264. #endif                    /* DeBugLinker */
  265.  
  266. /*
  267.  * alsolink - create an lfile structure for the named file and add it to the
  268.  *  end of the list of files (llfiles) to generate link instructions for.
  269.  */
  270. static char *pptr;
  271. novalue alsolink(name)
  272. char *name;
  273.    {
  274.    struct lfile *nlf, *p;
  275.    char file[256], ok;
  276.  
  277.    ok = 0;
  278.    if (canread(name)) {
  279.       ok++;
  280.       strcpy(file, name);
  281.       }
  282.    else {
  283.       /*
  284.        * Can't find name in current directory so try paths in
  285.        *   IPATH if there are any. (IPATH cannot override the
  286.        *   current-directory-first strategy so there is probably
  287.        *   no reason to initialize IPATH to the various current
  288.        *   directory markers as is done above, since this will
  289.        *   only result in a duplicate failed search. Note that
  290.        *   the access test which is done above in some systems
  291.        *   will have already caused ilink to exit if name is
  292.        *   not found in the current directory anyway so ipath
  293.        *   was never able to search other paths first in any case.)
  294.        */
  295.  
  296.  
  297.       pptr = ipath;
  298.  
  299.       while (trypath(name, file)) {
  300.          if (canread(file)) {
  301.             ok++;
  302.             break;
  303.             }
  304.          }
  305.       }
  306.  
  307.    if (!ok)
  308.      quitf("cannot resolve reference to file '%s'",name);
  309.  
  310.    nlf = alclfile(file);
  311.    if (llfiles == NULL) {
  312.       llfiles = nlf;
  313.       }
  314.    else {
  315.       p = llfiles;
  316.       while (p->lf_link != NULL) {
  317.         if (strcmp(p->lf_name,file) == 0)
  318.            return;
  319.         p = p->lf_link;
  320.         }
  321.       if (strcmp(p->lf_name,file) == 0)
  322.         return;
  323.       p->lf_link = nlf;
  324.       }
  325.    }
  326.  
  327. /*
  328.  * getlfile - return a pointer (p) to the lfile structure pointed at by lptr
  329.  *  and move lptr to the lfile structure that p points at.  That is, getlfile
  330.  *  returns a pointer to the current (wrt. lptr) lfile and advances lptr.
  331.  */
  332. struct lfile *getlfile(lptr)
  333. struct lfile **lptr;
  334.    {
  335.    struct lfile *p;
  336.  
  337.    if (*lptr == NULL)
  338.       return (struct lfile *)NULL;
  339.    else {
  340.       p = *lptr;
  341.       *lptr = p->lf_link;
  342.       return p;
  343.       }
  344.    }
  345.  
  346. /*
  347.  * canread - see if file can be read and be sure that it's just an
  348.  *  ordinary file.
  349.  */
  350. static int canread(file)
  351. char *file;
  352.    {
  353.  
  354. /*
  355.  * The following code is operating-system dependent [@lmem.03]. Check to see if
  356.  *  .u1 file can be read.
  357.  */
  358.  
  359. #if PORT
  360.    /* something is needed */
  361. Deliberate Syntax Error
  362. #endif                    /* PORT */
  363.  
  364. #if AMIGA
  365.    char lclname[MaxFileName];
  366.    if (access(makename(lclname,TargetDir,file,U1Suffix),4) == 0)
  367.       if (getfa(lclname) == -1)
  368.          return 1;
  369. #endif                    /* AMIGA */
  370.  
  371. #if ATARI_ST || HIGHC_386
  372.    {
  373.    FILE *f;
  374.    char lclname[MaxFileName];
  375.    if ((f = fopen(makename(lclname,TargetDir,file,U1Suffix), ReadText)) == NULL)
  376.       return 0;
  377.    else {
  378.       fclose(f);
  379.       return 1;
  380.       }
  381.    }
  382. #endif                    /* ATARI_ST || HIGHC_386 */
  383.  
  384. #if MACINTOSH
  385. #if MPW || LSC
  386.    {
  387.    FILE *f;
  388.    if ((f = fopen(file,ReadText)) != NULL) {
  389.       fclose(f);
  390.       return 1;
  391.       }
  392.    }
  393. #endif                    /* MPW || LSC */
  394. #endif                    /* MACINTOSH */
  395.  
  396. #if MSDOS
  397. #if MICROSOFT || TURBO
  398.    struct stat statb;
  399.    if (access(file,4) == 0) {
  400.       stat(file,&statb);
  401.       if (statb.st_mode & S_IFREG)
  402.          return 1;
  403.       }
  404. #else                    /* MICROSOFT || TURBO */
  405.    char lclname[MaxFileName];
  406.    if (access( makename(lclname,TargetDir,file,U1Suffix), 4 ) == 0 )
  407.       return 1;
  408. #endif                    /* MICROSOFT || TURBO */
  409. #endif                    /* MSDOS */
  410.  
  411. #if MVS || VM
  412. #if SASC
  413.    char lclname[MaxFileName];
  414.    if (access(makename(lclname,(char*)NULL,file,U1Suffix),R_OK) == 0)
  415.       return 1;
  416. #else                    /* SASC */
  417.    FILE *f;                     /* can't use access because it will */
  418.                                 /* accept LRECL, etc. */
  419.  
  420.    if ((f = fopen(file,"r")) != NULL {
  421.       fclose(f);
  422.       return 1;
  423.       }
  424. #endif                    /* SASC */
  425. #endif                    /* MVS || VM */
  426.  
  427. #if OS2
  428. #if MICROSOFT
  429.    struct stat statb;
  430.    if (access(file,4) == 0) {
  431.       stat(file,&statb);
  432.       if (statb.st_mode & S_IFREG)
  433.          return 1;
  434.       }
  435. #endif                    /* MICROSOFT || TURBO */
  436. #endif                    /* OS2 */
  437.  
  438. #if UNIX
  439.    struct stat statb;
  440.    if (access(file,4) == 0) {
  441.       stat(file,&statb);
  442.       if (statb.st_mode & S_IFREG)
  443.          return 1;
  444.       }
  445. #endif                    /* UNIX */
  446.  
  447. #if VMS
  448.    if (access(file,4) == 0)
  449.       return 1;
  450. #endif                    /* VMS */
  451.  
  452. /*
  453.  * End of operating-system specific code.
  454.  */
  455.  
  456.    return 0;
  457.    }
  458.  
  459.  
  460. /*
  461.  * trypath - form a file name in file by concatenating name onto the
  462.  *  next path element.
  463.  */
  464. static int trypath(name,file)
  465. char *name, *file;
  466.    {
  467.    char c;
  468.  
  469.    while (*pptr == ' ')
  470.       pptr++;
  471.    if (!*pptr)
  472.       return 0;
  473.    do {
  474.       c = (*file++ = *pptr++);
  475.       }
  476.       while (c != ' ' && c);
  477.    pptr--;
  478.    file--;
  479.  
  480. /*
  481.  * The following code is operating-system dependent [@lmem.04].  Append path
  482.  *  character.
  483.  */
  484.  
  485. #if PORT
  486.    /* nothing is needed */
  487. Deliberate Syntax Error
  488. #endif                    /* PORT */
  489.  
  490. #if AMIGA
  491.    file--;
  492.    switch (*file) {
  493.  
  494.       case ':':
  495.       case '/':
  496.                  file++;
  497.                  break;       /* add nothing, delimiter already there */
  498.       default:
  499.                  *file++ = '/';
  500.       }
  501. #endif                    /* AMIGA */
  502.  
  503. #if ATARI_ST || MACINTOSH || MVS || VM || VMS
  504.    /* nothing is needed */
  505. #endif                    /* ATARI_ST || MACINTOSH */
  506.  
  507. #if HIGHC_386
  508.    *file++ = '\\';
  509. #endif                    /* HIGHC_386 */
  510.  
  511. #if UNIX || MSDOS || OS2
  512.    *file++ = '/';            /* should check for delimiter */
  513. #endif                    /* UNIX || MSDOS || OS2 */
  514.  
  515. /*
  516.  * End of operating-system specific code.
  517.  */
  518.  
  519.    while (*file++ = *name++);
  520.    *file = 0;
  521.    return 1;
  522.    }
  523.  
  524. /*
  525.  * alclfile - allocate an lfile structure for the named file, fill
  526.  *  in the name and return a pointer to it.
  527.  */
  528. static struct lfile *alclfile(name)
  529. char *name;
  530.    {
  531.    struct lfile *p;
  532.  
  533.    p = (struct lfile *) alloc(sizeof(struct lfile));
  534.    p->lf_link = NULL;
  535.    p->lf_name = salloc(name);
  536.    return p;
  537.    }
  538.  
  539. #ifdef MultipleRuns
  540. /*
  541.  * freelfile - free memory of an lfile structure.
  542.  */
  543. static novalue freelfile(p)
  544. struct lfile *p;
  545.    {
  546.    free(p->lf_name);
  547.    free((char *) p);
  548.    }
  549. #endif                        /* MultipleRuns */
  550.  
  551. /*
  552.  * lmfree - free memory used by the linker
  553.  */
  554. novalue lmfree()
  555.    {
  556.    struct lfile *lf, *nlf;
  557.  
  558.    free((char *) lghash);   lghash = NULL;
  559.    free((char *) lihash);   lihash = NULL;
  560.    free((char *) lfhash);   lfhash = NULL;
  561.    free((char *) lltable);   lltable = NULL;
  562.    free((char *) lctable);   lctable = NULL;
  563.    free((char *) lftable);   lftable = NULL;
  564.    free((char *) lgtable);   lgtable = NULL;
  565.    free((char *) litable);   litable = NULL;
  566.    free((char *) lntable);   lntable = NULL;
  567.    free((char *) lrtable);   lrtable = NULL;
  568.    free((char *) lsspace);   lsspace = NULL;
  569.    free((char *) fnmtbl);   fnmtbl = NULL;
  570.    free((char *) labels);   labels = NULL;
  571.    free((char *) codep);   codep = NULL;
  572.  
  573. #ifdef MultipleRuns
  574.    for (lf = llfiles; lf != NULL; lf = nlf) {
  575.       nlf = lf->lf_link;
  576.       freelfile(lf);
  577.       }
  578.    llfiles = NULL;
  579.  
  580. #if MACINTOSH
  581. #if MPW
  582. /* #pragma unused(nlf,lf) */
  583. #endif                    /* MPW */
  584. #endif                    /* MACINTOSH */
  585. #endif                    /* MultipleRuns */
  586.  
  587.    }
  588.